/**
 *    Copyright (c) [2021] [白晓明]
 *    [IMHarmonyOSLib] is licensed under Mulan PSL v2.
 *    You can use this software according to the terms and conditions of the Mulan PSL v2.
 *    You may obtain a copy of Mulan PSL v2 at:
 *             http://license.coscl.org.cn/MulanPSL2
 *    THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 *    See the Mulan PSL v2 for more details.
 */
package com.itming.ui.coptlib.core;

import com.itming.ui.coptlib.ResourceTable;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

import java.io.IOException;

public class IMTextField extends TextField implements Component.DrawTask,
        Component.FocusChangedListener, Text.TextObserver {
    private static final String TAG = "IMTextField";
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x20001, TAG);

    public IMTextField(Context context) {
        this(context, null);
    }

    public IMTextField(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public IMTextField(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        if (attrSet.getAttr("style").isPresent()) {
            styleName = attrSet.getAttr("style").get().getStringValue();
        }
        initImTextField(context, attrSet);
    }

    /**
     * 初始化组件
     * @param context
     * @param attrSet
     */
    private void initImTextField(Context context, AttrSet attrSet) {
        setMultipleLine(false);
        if (attrSet.getAttr("border").isPresent()) {
            setBorder(attrSet.getAttr("border").get().getStringValue());
        } else {
            setBorder(null);
        }
        if (attrSet.getAttr("border_color").isPresent()) {
            setBorderColor(attrSet.getAttr("border_color").get().getColorValue());
        } else {
            setBorderColor(Color.BLUE);
        }

        if (attrSet.getAttr("border_width").isPresent()) {
            setBorderWidth(attrSet.getAttr("border_width").get().getIntegerValue());
        } else {
            setBorderWidth(5);
        }

        if (attrSet.getAttr("right_icon").isPresent()) {
            setRightIcon(attrSet.getAttr("right_icon").get().getStringValue());

            //右侧图标按钮
            initRightIconBtn();
        } else {
            setRightIcon(null);
        }
        //绘制边框
        initPaint();
        addDrawTask(this::onDraw);

        //设置光标气泡样式
        PixelMapElement element = null;
        try {
            element = new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_edit));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }
        setBubbleElement(element);
        setBubbleSize(48, 48);
    }

    /**
     * 右侧图标按钮
     */
    private void initRightIconBtn() {
        try {
            switch (getRightIcon()) {
                case "clear":
                    mElement = new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_clear));
                    break;
                case "unlock":
                    mElement = new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_unlock));
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }
        mElement.setBounds(0,0, 64, 64);

        if (getText().length() > 0) {
            setClearIconVisible(true);
        } else {
            setClearIconVisible(false);
        }
        //设置焦点改变的监听
        setFocusChangedListener(this);
        //设置输入框里面内容发生改变的监听
        addTextObserver(this);
        setTouchEventListener();
    }

    /**
     * 点击右侧按钮事件
     */
    private void setTouchEventListener() {
        setTouchEventListener((component, touchEvent) -> {
            if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP) {
                MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
                float x = point.getX();
                float y = point.getY();

                //获取删除图标的边界，返回一个Rect对象
                Rect bounds = mElement.getBounds();

                //判断触摸点是否在水平范围内
                boolean isInnerWidth = (x < getWidth()) &&
                        (x > (getWidth() - getPaddingRight() - getAroundElementsPadding() * 2 - bounds.getWidth()));


                boolean isInnerHeight = y < getHeight();
                if (isInnerHeight && isInnerWidth) {
                    changeRightIconState();
                }
            }
            return false;
        });
    }


    /**
     * 点击右侧按钮文本样式变化
     */
    private void changeRightIconState() {
        switch (getRightIcon()) {
            case "clear":
                setText("");
                break;
            case "unlock":
                changedTextInputType("lock");
                setTextInputType(InputAttribute.PATTERN_TEXT);
                break;
            case "lock":
                changedTextInputType("unlock");
                setTextInputType(InputAttribute.PATTERN_PASSWORD);
                break;
        }
    }

    /**
     * 更改密码框类型
     * @param str
     */
    private void changedTextInputType(String str) {
        try {
            if (str.equals("unlock")) {
                setRightIcon("unlock");
                mElement = new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_unlock));
            } else {
                setRightIcon("lock");
                mElement = new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_lock));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }
        mElement.setBounds(0,0, 64, 64);
    }

    private void initPaint() {
        if (!getBorder().isEmpty()) {
            paint = new Paint();
            paint.setColor(getBorderColor());
            paint.setStrokeWidth(getBorderWidth());
            paint.setStyle(Paint.Style.STROKE_STYLE);
        }
    }

    /**
     * 设置清除按钮显示隐藏
     * @param visible
     */
    private void setClearIconVisible(boolean visible) {
        Element right = visible ? mElement : null;
        setAroundElements(null, null, right, null);
        setAroundElementsPadding(20);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (!getBorder().isEmpty()) {
            String[] border = getBorder().split("\\|");
            for (int i = 0; i < border.length; i++) {
                HiLog.debug(LABEL, border[i]);
                switch (border[i]) {
                    case "left":
                        canvas.drawLine(0, 0, 0, getHeight(), paint);
                        break;
                    case "right":
                        canvas.drawLine(getWidth(),0, getWidth(), getHeight(), paint);
                        break;
                    case "top":
                        canvas.drawLine(0,0, getWidth(), 0, paint);
                        break;
                    case "bottom":
                        canvas.drawLine(0,getHeight(), getWidth(), getHeight(), paint);
                        break;
                }
            }
        }
    }


    @Override
    public void onFocusChange(Component component, boolean b) {
        this.hasFocus = b;
        if (hasFocus) {
            setClearIconVisible(getText().length() > 0);
        } else {
            setClearIconVisible(false);
        }
    }


    @Override
    public void onTextUpdated(String s, int i, int i1, int i2) {
        if (hasFocus) {
            setClearIconVisible(s.length() > 0);
        }
    }


    private Paint paint;
    /**
     * 自定义边框
     */
    private String border;

    /**
     * 自定义边框颜色
     */
    private Color borderColor;

    /**
     * 自定义边框宽度
     */
    private Integer borderWidth;

    /**
     * 右侧图标
     */
    private String rightIcon;


    private Element mElement;

    private Context context;

    private boolean hasFocus;

    public String getBorder() {
        return this.border;
    }

    public void setBorder(final String border) {
        this.border = border;
    }

    public Color getBorderColor() {
        return this.borderColor;
    }

    public void setBorderColor(final Color borderColor) {
        this.borderColor = borderColor;
    }

    public Integer getBorderWidth() {
        return this.borderWidth;
    }

    public void setBorderWidth(final Integer borderWidth) {
        this.borderWidth = borderWidth;
    }

    public String getRightIcon() {
        return this.rightIcon;
    }

    public void setRightIcon(final String rightIcon) {
        this.rightIcon = rightIcon;
    }

}
